﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace QA_System
{
    class TrieScanResult
    {
        public List<int> path;
        public string EAT;
        public string[] keyword;
        public TrieScanResult()
        {
            EAT = "";
            path = new List<int>();
            keyword = new string[5];
        }
    }


    static class  Trie
    {
        public static  TrieNode root;

        static public void CreateTrieFromXmlFile(string xmlFilePath)
        {
            root = new TrieNode(0, "", false, "");
            XmlDocument trieFile = new XmlDocument();            
            trieFile.Load(xmlFilePath);
            XmlNodeList begin = trieFile.GetElementsByTagName("begin");
            GetChildrenNode(begin.Item(0), root);
            //foreach (XmlNode questionPattern in questionPatternList)
            //{
            //    if (questionPattern.Attributes["keyword"].Value.ToString() == "") isKeyWord = false;
            //    else isKeyWord = true;
            //    temp = new TrieNode(Int32.Parse(questionPattern.Attributes["id"].Value.ToString()), questionPattern.Attributes["name"].Value.ToString(), isKeyWord, questionPattern.Attributes["EAT"].Value.ToString());
            //    root.AddChild(temp);
            //    GetChildrenNode(questionPattern, temp);      
            //}
        }

        static private void GetChildrenNode(XmlNode fatherNode, TrieNode fatherTrieNode)
        {
            TrieNode temp;
            bool isKeyWord;            
            if (fatherNode.HasChildNodes)
            {
                XmlNodeList childrenNodeList = fatherNode.ChildNodes;
                foreach (XmlNode child in childrenNodeList)
                {
                    
                    if (child.Attributes["keyword"].Value.ToString() == "") isKeyWord = false;
                    else isKeyWord = true;
                    temp = new TrieNode(Int32.Parse(child.Attributes["id"].Value.ToString()), child.Attributes["name"].Value.ToString(), isKeyWord, child.Attributes["EAT"].Value.ToString());
                    fatherTrieNode.AddChild(temp);
                    System.Console.WriteLine(temp.Name);
                    GetChildrenNode(child, temp);
                }
            }
            
        }
        
        //lay danh sach cac hien vat co trong file xml
        static private List<string> GetExhibitList()
        {
            XmlDocument exhibitFile = new XmlDocument();
            string exhibitFilePath = QA_System.Properties.Settings.Default.xmlDatabasePath + "ExhibitCollection.xml";
            List<string> exhibitArray = new List<string>();
            exhibitFile.Load(exhibitFilePath);
            XmlNodeList exhibitList = exhibitFile.GetElementsByTagName("exhibit");
            foreach (XmlNode item in exhibitList)
            {
                exhibitArray.Add(item.InnerText);
            }
            return exhibitArray;
        }

        static private string FixKeyword(string keyword, List<string> exhibitList)
        {
            string fixedKeyword = "";
            foreach (var item in exhibitList)
            {
                if (keyword.Contains(item))
                {
                    fixedKeyword = item;
                    break;
                }                
            }
            if (fixedKeyword == "")
                fixedKeyword = keyword;
            return fixedKeyword;
        }

        static public TrieScanResult ScanTrieToGetEAT(sentence_tagger sentence)
        {
            TrieScanResult result = new TrieScanResult();
            TrieNode currentNode = Trie.root;
            TrieNode temp = new TrieNode();            
            int keywordNum = 0;
            List<string> exhibitList = new List<string>();
            string meaninglessWord = "xin cho biết/xin vui lòng cho tôi/bạn có thể/hãy cho tôi biết/do/bị/được không/là/coi/nên/của/hãy/cho biết/hiện vật/thế còn/đồ/trưng bày/về/cho biết/một số/một vài/một ít/những/tôi/từ/bằng/nguyên liệu/chất liệu/cái/đâu/gì/nào/ở/đã/như thế nào/ra sao/để làm gì/cần/người";
            string keywordTemp = "";
            int i = 0;
            exhibitList = GetExhibitList();
            while (i < sentence.Sentence_length)
            {       
                // neu node co node con chua tu dang xet
                temp = currentNode.GetChildByName(sentence[i].Word_text.ToLower());
                if (temp.Id != -1)
                {
                    //neu node hien tai la keyword thi gan keywordTemp thanh keyword
                    if ((currentNode.Name == "*") && (keywordTemp != ""))
                    {
                        result.keyword[keywordNum] = keywordTemp.Trim();
                        ++keywordNum;
                        keywordTemp = "";
                        if ((currentNode.EAT != ""))
                        {
                            result.EAT = currentNode.EAT;
                        } 
                    }                    
                    currentNode = temp;
                    result.path.Add(currentNode.Id);
                    if ((currentNode.EAT != ""))
                    {
                        result.EAT = currentNode.EAT;
                    }                     
                }
                //neu node con cua node hien tai ko chua tu dang xet, tu dang xet khong phai la tu vo nghia
                else if (!meaninglessWord.Contains(sentence[i].Word_text)) 
                {
                    // neu node dang xet la keyword   
                    if (currentNode.Name == "*")
                    {
                        //them tu dang xet vao keywordTemp
                        keywordTemp += sentence[i].Word_text.ToLower();
                        keywordTemp += " ";
                        //neu tu dang xet la tu cuoi cung và keywordTemp ko rong --> gán keywordTemp thanh keyword
                        if ((i == sentence.Sentence_length - 1) && (keywordTemp != ""))
                        {
                            result.keyword[keywordNum] = keywordTemp.Trim();
                            ++keywordNum;
                            keywordTemp = "";
                            if ((currentNode.EAT != ""))
                            {
                                result.EAT = currentNode.EAT;
                            }
                        }
                        
                    }
                    //nếu node dang xet ko la keyword
                    else
                    {
                        //neu node hien tai co node con la keyword
                        temp = currentNode.GetChildByName("*");
                        if (temp.Id != -1)
                        {

                            currentNode = temp;
                            result.path.Add(currentNode.Id);
                            if ((currentNode.EAT != ""))
                            {
                                result.EAT = currentNode.EAT;
                            }
                            if (sentence[i].Word_pos == "Np")
                            {
                                result.keyword[keywordNum] = sentence[i].Word_text;
                                ++keywordNum;
                            }
                            else
                            {
                                keywordTemp += sentence[i].Word_text.ToLower();
                                keywordTemp += " ";
                            }
                        }
                        else
                        {
                            keywordTemp += sentence[i].Word_text.ToLower();
                            keywordTemp += " ";
                        }
                    }
                }
                
                ++i;
                if ((i == sentence.Sentence_length))
                {
                    if ((currentNode.Name == "*") && (keywordTemp != ""))
                    {
                        result.keyword[keywordNum] = keywordTemp.Trim();
                        ++keywordNum;
                        keywordTemp = "";                        
                    }
                    if ((currentNode.EAT != ""))
                    {
                        result.EAT = currentNode.EAT;
                    }
                    for (int j = 0; j < keywordNum; j++)
                    {
                        result.keyword[j] = FixKeyword(result.keyword[j], exhibitList);
                    }
                    if (result.EAT == "")
                    {
                        result.EAT = "Exception";
                    }
                    
                }

            }
            return result;      
            
        }
    
    }
}
